﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Auth.SqlSugar.IRepositories;
using Auth.Utility;
using Microsoft.Extensions.Configuration;
using SqlSugar;

namespace Auth.SqlSugar.Repositories
{
    public class BaseRepository<T> : IBaseRepository<T> where T : class, new()
    {
        public BaseRepository()
        {
        }
        /// <summary>
        /// 插入数据 返回受影响行数
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        public int Insert(T entity)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Insertable<T>(entity).ExecuteCommand();
            }
        }

        /// <summary>
        /// 插入数据,删除缓存 返回受影响行数
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        public int InsertWithCache(T entity)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                if(RedisCache.UseCache)
                    return dbClient.Insertable<T>(entity).RemoveDataCache().ExecuteCommand();
                else
                    return dbClient.Insertable<T>(entity).ExecuteCommand();
            }
        }

        /// <summary>
        /// 批量插入数据
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <returns></returns>
        public int InsertRange(List<T> entities)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                try
                {
                    dbClient.Ado.BeginTran();
                    return dbClient.Insertable(entities.ToArray()).ExecuteCommand();
                }
                catch (Exception ex)
                {
                    dbClient.Ado.RollbackTran();
                    throw new Exception(ex.Message);
                }
            }
        }

        /// <summary>
        /// 批量插入数据,删除缓存
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <returns></returns>
        public int InsertRangeWithCache(List<T> entities)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                try
                {
                    dbClient.Ado.BeginTran();
                    return dbClient.Insertable(entities.ToArray()).ExecuteCommand();
                }
                catch (Exception ex)
                {
                    dbClient.Ado.RollbackTran();
                    throw new Exception(ex.Message);
                }
            }
        }
        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int Delete(string id)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Deleteable<T>().In(id).ExecuteCommand();
            }
        }
        /// <summary>
        /// 根据主键批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public int Delete(List<string> ids)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Deleteable<T>().In(ids).ExecuteCommand();
            }
        }
        /// <summary>
        /// 根据实体删除
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int Delete(T t)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Deleteable<T>().Where(t).ExecuteCommand();
            }
        }
        /// <summary>
        /// 根据实体集合删除
        /// </summary>
        /// <param name="tList"></param>
        /// <returns></returns>
        public int Delete(List<T> tList)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Deleteable<T>().Where(tList).ExecuteCommand();
            }
        }

        /// <summary>
        /// 更新(根据主键)
        /// </summary>
        /// <param name="model">实体对象</param>
        /// <returns></returns>
        public int Update(T model)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Updateable(model).ExecuteCommand();
            }
        }

        /// <summary>
        /// 更新(根据主键)
        /// </summary>
        /// <param name="model">实体对象</param>
        /// <param name="whereExpression">表达式</param>
        /// <returns></returns>
        public int Update(T model, Expression<Func<T, bool>> whereExpression)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Updateable(model).Where(whereExpression).ExecuteCommand();
            }
        }

        /// <summary>
        /// 批量更新(根据主键)
        /// </summary>
        /// <param name="model">entity</param>
        /// <returns></returns>
        public int Update(List<T> model)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                try
                {
                    dbClient.Ado.BeginTran();
                    return dbClient.Updateable(model).ExecuteCommand();
                }
                catch (Exception ex)
                {
                    dbClient.Ado.RollbackTran();
                    throw new Exception(ex.Message);
                }
            }
        }

        /// <summary>
        /// 查询一个
        /// </summary>
        /// <returns></returns>
        public T QuerySingle()
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().Single();
            }
        }

        /// <summary>
        /// 根据主键查询
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public T QuerySingle(string id)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().InSingle(id);
            }
        }

        /// <summary>
        /// 查询所有
        /// </summary>
        /// <returns></returns>
        public List<T> QueryAll()
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().ToList();
            }
        }

        /// <summary>
        /// 按条件查询
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="orderExpression">排序表达式</param>
        /// <param name="orderType">排序方式</param>
        /// <returns></returns>
        public List<T> QueryByWhere(Expression<Func<T, bool>> whereExpression,
            Expression<Func<T, object>> orderExpression, OrderByType orderType = OrderByType.Asc)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().WhereIF(whereExpression != null, whereExpression).OrderByIF(orderExpression != null, orderExpression, orderType).ToList();
            }
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="searchParam"></param>
        /// <param name="orderExpression"></param>
        /// <param name="orderType"></param>
        /// <returns></returns>
        public List<T> QueryByWherePage(int pageIndex, int pageSize, List<IConditionalModel> searchParam,
            string orderFields)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().Where(searchParam).OrderByIF(!string.IsNullOrEmpty(orderFields.Trim()), orderFields)
                    .ToPageList(pageIndex, pageSize);
            }
        }

        /// <summary>
        /// 查询指定个数的数据
        /// </summary>
        /// <param name="takeNum">指定个数</param>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="orderExpression">排序表达式</param>
        /// <param name="orderType">排序方式</param>
        /// <returns></returns>
        public List<T> QueryTop(int takeNum, Expression<Func<T, bool>> whereExpression = null,
            Expression<Func<T, object>> orderExpression = null, OrderByType orderType = OrderByType.Asc)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().WhereIF(whereExpression != null, whereExpression).OrderByIF(orderExpression != null, orderExpression, orderType).Take(takeNum)
                    .ToList();
            }
        }
        /// <summary>
        /// 查询条数
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        public int QueryCount(Expression<Func<T, bool>> whereExpression = null)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().WhereIF(whereExpression != null, whereExpression).Count();
            }
        }

        /// <summary>
        /// 查询条数
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        public int QueryCount(List<IConditionalModel> searchParam)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().Where(searchParam).Count();
            }
        }

        /// <summary>
        /// 查询是否存在记录
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        public bool Any(Expression<Func<T, bool>> whereExpression)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().Any(whereExpression);
            }
        }

        /// <summary>
        /// 执行sql语句或存储过程
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="sql">sql语句</param>
        /// <param name="whereObj">命令参数对应匿名对象</param>
        /// <returns></returns>
        public List<TResult> QueryBySql<TResult>(string sql, object whereObj = null)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Ado.SqlQuery<TResult>(sql, whereObj);
            }
        }

        /// <summary>
        /// 事务执行sql语句或存储过程
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="sql">sql语句</param>
        /// <param name="whereObj">命令参数对应匿名对象</param>
        /// <returns></returns>
        public List<TResult> QueryBySqlTransactions<TResult>(string sql, object whereObj = null)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                try
                {
                    dbClient.Ado.BeginTran();
                    return dbClient.Ado.SqlQuery<TResult>(sql, whereObj);
                }
                catch (Exception ex)
                {
                    dbClient.Ado.RollbackTran();
                    throw new Exception(ex.Message);
                }
            }
        }

        public int DeleteWithCache(string id)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                if(RedisCache.UseCache)
                    return dbClient.Deleteable<T>().In(id).RemoveDataCache().ExecuteCommand();
                else
                    return dbClient.Deleteable<T>().In(id).ExecuteCommand();
            }
        }

        public int DeleteWithCache(List<string> ids)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                if(RedisCache.UseCache)
                    return dbClient.Deleteable<T>().In(ids).RemoveDataCache().ExecuteCommand();
                else
                    return dbClient.Deleteable<T>().In(ids).ExecuteCommand();
            }
        }

        public int DeleteWithCache(T t)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                if(RedisCache.UseCache)
                    return dbClient.Deleteable<T>().Where(t).RemoveDataCache().ExecuteCommand();
                else
                    return dbClient.Deleteable<T>().Where(t).ExecuteCommand();
            }
        }

        public int DeleteWithCache(List<T> tList)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                if(RedisCache.UseCache)
                    return dbClient.Deleteable<T>().Where(tList).RemoveDataCache().ExecuteCommand();
                else
                    return dbClient.Deleteable<T>().Where(tList).ExecuteCommand();
            }
        }

        public int UpdateWithCache(T model)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                if(RedisCache.UseCache)
                    return dbClient.Updateable(model).RemoveDataCache().ExecuteCommand();
                else
                    return dbClient.Updateable(model).ExecuteCommand();
            }
        }

        public List<T> QueryAllWithCache()
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().WithCacheIF(RedisCache.UseCache,3600).ToList();
            }
        }

        public List<T> QueryByWhereWithCache(Expression<Func<T, bool>> whereExpression, Expression<Func<T, object>> orderExpression, OrderByType orderType = OrderByType.Asc)
        {
            using (SqlSugarClient dbClient = DbInstance.GetInstance())
            {
                return dbClient.Queryable<T>().WhereIF(whereExpression != null, whereExpression).OrderByIF(orderExpression != null, orderExpression, orderType).WithCacheIF(RedisCache.UseCache, 3600).ToList();
            }
        }
    }
}